package org.arch_learn.io.netty_demo.chatroom;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class NettyChatServer {
    private int port;

    public NettyChatServer(int port) {
        this.port = port;
    }

    public void run() throws InterruptedException {
        EventLoopGroup bossGroup = null;
        EventLoopGroup workerGroup = null;
        try {
            //1.创建bossGroup线程组，处理网络连接事件(主线程组设置2个线程,不设置的话默认为处理器线程数）
            bossGroup = new NioEventLoopGroup(2);
            //2.创建workGroup线程组，处理网络读写事件(从线程组设置10个线程,不设置的话默认为处理器线程数 * 2）
            workerGroup = new NioEventLoopGroup(10);
            //3.创建服务端启动助手
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            //4.设置bossGroup线程组和workGroup线程组
            serverBootstrap.group(bossGroup, workerGroup)
                    //5.设置服务端通道（serverSocketChannel)为NIO
                    .channel(NioServerSocketChannel.class)
                    //6.bossGroup参数设置(设置连接等待个数)
                    .option(ChannelOption.SO_BACKLOG, 128)
                    //7.workGroup参数设置(设置活跃状态)
                    .childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE)
                    //8.创建一个通道初始化对象
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel channel) throws Exception {
                            //9.向pipeline中添加自定义业务处理handler
                            ChannelPipeline pipeline = channel.pipeline();
                            //todo
                            //添加解码器
                            pipeline.addLast("messageDecoder", new StringEncoder());
                            //添加编码器
                            pipeline.addLast("messageEncoder", new StringDecoder());
//                            //添加编解码器
//                            pipeline.addLast(new MessageCodec());
                            pipeline.addLast(new NettyChatServerHandler());

                        }
                    });
            //10.启动服务端并绑定端口，同时将异步改成同步
            ChannelFuture channelFuture = serverBootstrap.bind(9999);
//                .sync();
            channelFuture.addListener((ChannelFutureListener) channelFuture1 -> {
                if (channelFuture1.isSuccess()) {
                    System.out.println("端口绑定成功！");
                } else {
                    System.out.println("端口绑定失败！");
                }
            });
            System.out.println("Netty聊天室服务端启动成功！");
            //11.关闭通道(并不是真正意义上的关闭，而是监听通道关闭的状态)和关闭连接池
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //有通道关闭，才会执行下面代码，因为上一行代码的sync方法使线程阻塞在上一行了。
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }


    }

    public static void main(String[] args) throws InterruptedException {
        NettyChatServer nettyChatServer = new NettyChatServer(9998);
        nettyChatServer.run();
    }
}
